package vote.ai.utils;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import vote.ai.domain.enums.CorrectionModel;
import vote.ai.domain.vo.TextCorrectionMatchResp;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Description:
 * Author:han
 * Date: 2024-05-21
 */
@Slf4j
public class TextCorrectMatch {
    public static List<TextCorrectionMatchResp> obscureTextV1(CorrectionModel model, String originalText, String correctedText, String category, String source, String level) {
        if (originalText == null || correctedText == null) {
            return new ArrayList<>();
        }
        List<TextCorrectionMatchResp> diffList = new ArrayList<>();
        // 如果 error-text 里的错误内容和纠错后的内容相同，那么则需要删除掉 error-text 标签
        correctedText = handleErrorText(correctedText);
        if (originalText.endsWith("<br/>")) {
            originalText = originalText.substring(0, originalText.length() - 5);
        }
        if (correctedText.endsWith("<br/>")) {
            correctedText = correctedText.substring(0, correctedText.length() - 5);
        }
        //分割成句子
        List<String> originalSentences = splitIntoSentences(originalText);
        List<String> correctedSentences = splitIntoSentences(correctedText);
        if (originalSentences.size() != correctedSentences.size()) {
            if (originalText.equals(correctedText)) {
                return new ArrayList<>();
            }
            char lastChar = originalText.charAt(originalText.length() - 1);
            char corrChar = correctedText.charAt(correctedText.length() - 1);
            int endIndex = originalText.length() - 1;
            //如果一个是结束字符一个不是，则endIndex加1
            if (!isDelimiter(lastChar) && isDelimiter(corrChar)) {
                endIndex = endIndex + 1;
            }
            log.info("原始文本和纠正文本长度不一致，无法进行精确匹配。");
            diffList.add(new TextCorrectionMatchResp(model, source, model.getBeanName(), 0, endIndex, originalText, correctedText, LocalDateTime.now(), category, 0, level));
            log.info("原始文本和纠正文本长度不一致，无法进行精确匹配 DIFF:{}", JSON.toJSONString(diffList));
            return diffList;
        }//长度相同
        int i = 0;
        int j = 0;
        int originalOffset = 0;
        int correctedOffset = 0;
        while (i < originalSentences.size() && j < correctedSentences.size()) {
            String origSentence = originalSentences.get(i);
            String corrSentence = correctedSentences.get(j);
            int startIndex = originalOffset;
            int endIndex = startIndex + origSentence.length() - 1;
            if (!origSentence.equals(corrSentence)) {
                // 处理 <br/> 标签
                if (origSentence.contains("<br/>") && corrSentence.contains("<br/>")) {
                    origSentence = origSentence.replaceAll("<br/>", "");
                    corrSentence = corrSentence.replaceAll("<br/>", "");
                    endIndex = endIndex - 4; // 减去 <br/> 的长度（假设是 5 个字符）
                } else if (origSentence.contains("<br/>") && !corrSentence.contains("<br/>")) {
                    origSentence = origSentence.replaceAll("<br/>", "");
                    endIndex = endIndex - 4;
                } else if (corrSentence.contains("<br/>") && !origSentence.contains("<br/>")) {
                    corrSentence = corrSentence.replaceAll("<br/>", "");
                }
                // 如果原句字最后一个字符不是 标点，并且纠错后的句子后面是标点，那么则需要进行 endIndex +1
                // 取出 原句字 最后一个字符
                char lastChar = origSentence.charAt(origSentence.length() - 1);
                char corrChar = corrSentence.charAt(corrSentence.length() - 1);
                if (!isDelimiter(lastChar) && isDelimiter(corrChar)) {
                    endIndex = endIndex + 1;
                }
                diffList.add(new TextCorrectionMatchResp(model, model.getDesc(), source, startIndex, endIndex, origSentence, corrSentence, LocalDateTime.now(), category, 0, level));
                // 更新累计偏移量
                originalOffset += originalSentences.get(i).length();
                correctedOffset += correctedSentences.get(j).length();
                // 移动指针
                i++;
                j++;
            }
        }
        // 处理 correctedText 最后多余的句子
        while (j < correctedSentences.size()) {
            String extraSentence = correctedSentences.get(j);
            diffList.add(new TextCorrectionMatchResp(model, model.getDesc(), source, originalText.length(), originalText.length() - 1,
                    "", extraSentence, LocalDateTime.now(), category, 0, level));
            j++;
        }
        //合并相邻差异
        mergeDiffList(diffList);
        return diffList;
    }

    private static void mergeDiffList(List<TextCorrectionMatchResp> diffList) {
        List<TextCorrectionMatchResp> mergedDiffList = new ArrayList<>();
        for (TextCorrectionMatchResp currentDiff : diffList) {
            if (mergedDiffList.isEmpty()) {
                // 第一个差异，直接添加
                mergedDiffList.add(currentDiff);
            } else {
                TextCorrectionMatchResp prevDiff = mergedDiffList.get(mergedDiffList.size() - 1);
                if (currentDiff.getErrorStartIndex() == prevDiff.getErrorEndIndex() + 1) {
                    // 合并相邻的差异
                    prevDiff.setErrorEndIndex(currentDiff.getErrorEndIndex());
                    prevDiff.setErrorText(prevDiff.getErrorText() + currentDiff.getErrorText());
                    prevDiff.setCorrectText(prevDiff.getCorrectText() + currentDiff.getCorrectText());
                    continue;
                }
            }

            // 更新原列表
            diffList.clear();
            diffList.addAll(mergedDiffList);
        }

    }


    /**
     * 处理错误文本
     *
     * @param errorText 错误文本
     * @return 处理结果
     */
    private static String handleErrorText(String errorText) {
        //String text = "最后还是轻轻抽出了两只<error-text :绿豆冰棍>绿豆冰棍</error-text><error-text :>。</error-text>";
        String regex = "<error-text\\s*:\\s*([^>]*?)>(.*?)</error-text>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(errorText);
        StringBuilder result = new StringBuilder();
        int lastEnd = 0;
        while (matcher.find()) {
            // 先将上次匹配结束到这次匹配开始之间的文本（即未被标签包裹的部分）添加到结果中
            result.append(errorText.substring(lastEnd, matcher.end()));
            //获取标签内容冒号后
            String innerText = matcher.group(1);
            //获取标签内文本
            String content = matcher.group(2);
            if (!innerText.equals(content)) {
                result.append(matcher.group());
            } else {
                result.append(innerText);
            }
            lastEnd = matcher.end();
        }
        //加入标签外文本到结果集
        result.append(errorText.substring(lastEnd));
        return result.toString();
    }

    private static List<String> splitIntoSentences(String text) {
        List<String> sentences = new ArrayList<>();
        StringBuilder sentence = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            sentence.append(c);
            if (isDelimiter(c)) {//是一句话将这句加入结果集清空stringbuilder
                sentences.add(sentence.toString());
                sentence.setLength(0);
            }
        }
        if (!sentence.isEmpty()) {
            sentences.add(sentence.toString().trim());
        }
        return sentences;
    }

    /**
     * 判断字符是否为分隔符
     *
     * @param c 字符
     * @return 是否为分隔符
     */
    private static boolean isDelimiter(char c) {
        return c == '。' || c == '，' || c == '；' || c == '！' || c == '？' || c == ',' || c == '?' || c == '!' || c == ';';
    }

}
